﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Windows.Markup;
using System.Xml;

namespace editor
{
    /// <summary>
    /// Логика взаимодействия для life_time.xaml
    /// </summary>
    public partial class LifeLine : UserControl, UIViewProtocol
    {
        public bool current;
        //время жизни
        public Rectangle _reсt;

        public bool drop_rect;
        //перетаскивание
        public bool dro = true;

        public Line line_;

        //номер в канвасе
        public int id;

        public bool Remove;
        private Point po_;

        public LifeLine()
        {
            InitializeComponent();

            id = MainWindow.shared().getId();
            MainWindow.shared().lifeLinesList.Add(this);
        }

        public LifeLine initWithPoint(System.Windows.Point origin)
        {

            this.dro = false;

            // conventional mouse protocol
            //this.MouseLeftButtonDown += new MouseButtonEventHandler(MainWindow.shared().life_t_MouseLeftButtonDown);
            //this.MouseMove += new System.Windows.Input.MouseEventHandler(MainWindow.shared().life_t_MouseMove);
            ////life_t.MouseLeftButtonUp+=new MouseButtonEventHandler(MainWindow.shared().life_t_MouseLeftButtonUp);
            //this.PreviewMouseDown += new MouseButtonEventHandler(MainWindow.shared().life_t_PreviewMouseDown);
            //this.PreviewMouseLeftButtonUp += new MouseButtonEventHandler(MainWindow.shared().life_t_PreviewMouseLeftButtonUp);

            // new mouse protocol
            this.textBox.PreviewMouseDown += new MouseButtonEventHandler(mouseButtonDown);
            this.line.PreviewMouseDown += new MouseButtonEventHandler(lineClicked);

            //позиция на канвасе
            Canvas.SetTop(this, 20);
            Canvas.SetLeft(this, origin.X);

            return this;
        }

        public UIViewProtocol copy()
        {
            LifeLine copy = new LifeLine();
            copy.initWithPoint(new System.Windows.Point(Canvas.GetLeft(this), Canvas.GetTop(this)));
            copy.line.Y2 = this.line.Y2;
            copy.textBox.Text = this.textBox.Text;

            MainWindow.shared().mainCanvas.Children.Add(copy);

            return (UIViewProtocol)copy;
        }

        public void move(System.Windows.Point origin)
        {
            Canvas mainCanvas = MainWindow.shared().mainCanvas;

            Canvas.SetTop((this), 20);
            Canvas.SetLeft((this), origin.X);

            Mouse.Capture(null);
            // VisualCollection df = new VisualCollection();
            int childrenCount = mainCanvas.Children.Count;
            for (int j = 0; j < childrenCount; j++)
            {
                Arrow l1 = mainCanvas.Children[j] as Arrow;
                if (l1 != null)
                {
                    //находим принадлежащие  линии Жизни
                    if (l1.begin_el_n_FC == (this).id)
                    {
                        //передвигаем начало стрелки
                        double delta = 50;
                        l1.pos_line_B_X1(delta + origin.X);

                        l1.strelka_SizeChanged(l1.line, null);
                    }
                    if (l1.end_el_n_FC == (this).id)
                    {
                        //передвигаем  конец
                        double delta = 50;
                        l1.pos_line_E_X2(delta + origin.X);

                        l1.strelka_SizeChanged(l1.line, null);
                    }
                }
                SelfArrow l_return = mainCanvas.Children[j] as SelfArrow;

                //перерисовываем стрелку с возвратом
                if (l_return != null)
                {
                    if (l_return.numb_l_t_in_canvas == (this).id)
                    {
                        PointCollection asd = l_return.str_return.Points;
                        Point Begin_point = asd[0];
                        double delta = 70;
                        l_return.line_prop_str_return(delta + origin.X, Begin_point.Y);
                    }
                }
            }
        }

        private void Line_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (dro == true)
            {
                Line line = sender as Line;
                if (line != null)
                { Mouse.Capture((Line)sender); }
            }
            else
            {
                Line line = sender as Line;
                if (line != null)
                {
                    //Rectangle rest2 = new Rectangle();
                    //rest2.Fill = Brushes.Firebrick;
                    //rest2.Stroke = Brushes.Gainsboro;
                    //rest2.Width = 50;
                    //rest2.Height = 100;

                    //Canvas.SetTop(rest2, e.GetPosition(canvasfgh).Y);
                    //Canvas.SetLeft(rest2, e.GetPosition(canvasfgh).X - 10);
                    ////добавляем элементы 
                    //canvasfgh.Children.Add(rest2);
                }
               
            }

        }

        private void Line_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (dro == true)
            {
                Line line = sender as Line;
                if (line != null)
                {
                    Mouse.Capture((Line)sender);
                    Mouse.Capture(null);
                    //e.GetPosition((Line)sender).Y координата относительно начала линии

                    Double legth_AS = Math.Abs(e.GetPosition((Line)sender).Y - ((Line)sender).Y1);
                    if (legth_AS > 40)
                    {
                        ((Line)sender).Y2 = Math.Abs(e.GetPosition((Line)sender).Y - ((Line)sender).Y1) + 20;
                    }
                    dro = false;
                }
            }
        }

        private void Line_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (dro == true)
            {
                Line line = sender as Line;
                if (line != null)
                {
                    Mouse.Capture((Line)sender);
                    Mouse.Capture(null);
                    //e.GetPosition((Line)sender).Y координата относительно начала линии

                    Double legth_AS = Math.Abs(e.GetPosition((Line)sender).Y - ((Line)sender).Y1);
                    if (legth_AS > 40)
                    {
                        ((Line)sender).Y2 = Math.Abs(e.GetPosition((Line)sender).Y - ((Line)sender).Y1) + 20;
                    }
                }
            }
        }

        ///////////////////////////////////////////////////////////////////////////////
        //------------------------------рект-----------------------------------------//
        ///////////////////////////////////////////////////////////////////////////////
        //инилизация
        public Rectangle new_Rect(Double Height)
        {
            
            _reсt = new Rectangle();
            //-----------------рисуем  рект
            _reсt.Fill = Brushes.White;
            _reсt.StrokeThickness = 3;
            _reсt.Stroke = Brushes.Black;
            _reсt.Width = 20;
            if (Height == 0)
            {
                _reсt.Height = 52;
            }
            else
            {
                _reсt.Height = Height;
            }
            

            _reсt.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(_reсt_PreviewMouseLeftButtonDown);
            _reсt.PreviewMouseLeftButtonUp += new MouseButtonEventHandler(_reсt_PreviewMouseLeftButtonUp);
            _reсt.PreviewMouseMove += new MouseEventHandler(_reсt_PreviewMouseMove);

            return _reсt;
        }

      
        public void add_rect_canvac(Double X, Double Y)
        {
           //относительно линнии вставляем ректангл

            Double pos_X_0 = line.X1;

            Canvas.SetLeft(_reсt, pos_X_0 - 10);
            // добавляем координаты второго рект
            Canvas.SetTop(_reсt, Y - 21);
            localCanvas.Children.Add(_reсt);
        }
        //нажатие  клавиши
        void _reсt_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            
            if (drop_rect == false)
            {
                drop_rect = true;

                Rectangle R = sender as Rectangle;
                if (R != null)
                {
                    Mouse.Capture((Rectangle)sender);

                    po_.Y =   Canvas.GetTop((Rectangle)sender);

                }
            }
        }

        void _reсt_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {

            if (drop_rect == true)
            {
                Rectangle R = sender as Rectangle;
                if (R != null)
                {
                    Mouse.Capture((Rectangle)sender);
                    Mouse.Capture(null);

                    Double hegth_AS = Math.Abs(e.GetPosition(localCanvas).Y - po_.Y);
                    if (hegth_AS > 12)
                    {
                        ((Rectangle)sender).Height = hegth_AS + 20;
                    }
                }
                drop_rect = false;
            }
        }

        void _reсt_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {

            if (drop_rect == true)
            {
                Rectangle R = sender as Rectangle;
                if (R != null)
                {
                    Mouse.Capture((Rectangle)sender);
                    Mouse.Capture(null);

                    Double hegth_AS = Math.Abs(e.GetPosition(localCanvas).Y - po_.Y);
                    if (hegth_AS > 12)
                    {
                        ((Rectangle)sender).Height = hegth_AS + 20;
                    }
                }
            }
        }


        ///////////////////////////////////////////////////////////////////////////////
        //------------------------------рект-----------------------------------------//
        ///////////////////////////////////////////////////////////////////////////////
        public void savw_(string name_File)
        {

            FileStream fs = new FileStream(name_File, FileMode.Create);
            XamlWriter.Save(this.localCanvas, fs);
            fs.Close();
        }


        public void loa_(string name_File)
        {
            FileStream fs = new FileStream(name_File, FileMode.Open, FileAccess.Read);
            XmlReader xmlReader = XmlReader.Create(fs);

           
           // Canvas l_t = XamlReader.Load(xmlReader) as Canvas;
            this.localCanvas =(Canvas) XamlReader.Load(xmlReader) ;
            fs.Close();          
        }

        private void _line_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            //double lenth_li = _line.Y2 - _line.Y1;
            //double W_CHH, SUM = 0;
            //double h0 = 20;

            //LinearGradientBrush myHorizontalGradient = new LinearGradientBrush();
            //myHorizontalGradient.StartPoint = new Point(0.5, 1);
            //myHorizontalGradient.EndPoint = new Point(0.5, 0);
            //W_CHH = (h0 / lenth_li) / 3 ;
            //for (int i = 0; i < lenth_li / h0; i++)
            //{

            //    SUM += 2*W_CHH;

            //    myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Black, SUM));
            //    myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.White, SUM));
            //    SUM += W_CHH;
            //    myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.White, SUM));
            //    myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Black, SUM));
            //}
            //_line.Stroke = myHorizontalGradient;
           
        }

        private void dec_life_time(int index_life_time_del)
        {
            int Casd = MainWindow.shared().mainCanvas.Children.Count;
            //перебираем все стрелки
            for (int j = Casd - 1; j > 0; j--)
            {
                LifeLine bn = MainWindow.shared().mainCanvas.Children[j] as LifeLine;
                if (bn != null)
                {
                    if (bn.id > index_life_time_del)
                    {
                        bn.id--;

                    }
                }
                SelfArrow del_v_str = MainWindow.shared().mainCanvas.Children[j] as SelfArrow;
                if (del_v_str != null)
                {
                    if (del_v_str.el_n_FC > index_life_time_del)
                    {
                        del_v_str.el_n_FC--;
                    }
                }
                Arrow del_str = MainWindow.shared().mainCanvas.Children[j] as Arrow;
                if (del_str != null)
                {
                    if (del_str.begin_el_n_FC > index_life_time_del)
                    {
                        del_str.begin_el_n_FC--;
                    }
                    if (del_str.end_ei_n_TC > index_life_time_del)
                    {
                        del_str.end_ei_n_TC--;
                    }
                }

            }
        }

        private void delte_strlka_n_return(Canvas fd, int n_des_E, int count_Lif__FC)
        {
            int Casd = fd.Children.Count;
            //перебираем все стрелки
            for (int j = 0; j < Casd; j++)
            {
                Arrow bn = fd.Children[j] as Arrow;
                if (bn != null)
                {
                    //совпадает начало удаляемой lif_time и начало хранимое в стрелке
                    if (count_Lif__FC == bn.begin_el_n_FC)
                    {
                        if (bn.begin_el_n_TC > n_des_E)
                        {
                            bn.begin_el_n_TC--;
                        }
                    }
                    //совпадает начало удаляемой lif_time и конец хранимое в стрелке
                    if (count_Lif__FC == bn.end_el_n_FC)
                    {
                        if (bn.end_ei_n_TC > n_des_E)
                        {
                            bn.end_ei_n_TC--;
                        }

                    }

                }
                //стрелка с возвратом
                SelfArrow str_vozvrat = fd.Children[j] as SelfArrow;
                if (str_vozvrat != null)
                {
                    //совпалают линния хизни
                    if (count_Lif__FC == str_vozvrat.el_n_FC)
                    {
                        // индекс удаляемой срелки с возвратом меньше чем найденной
                        if (str_vozvrat.el_n_TC > n_des_E)
                        {
                            str_vozvrat.el_n_TC--;
                        }
                    }

                }
            }
        }


        private void removeArrow(Canvas fd, int n_des_B, int n_des_E, int count_Lif_begin_FC, int count_Lif_end_FC)
        {
            int Casd = fd.Children.Count;
              //перебираем все стрелки
            for (int j = 0; j < Casd; j++)
            {
                 Arrow bn = fd.Children[j] as Arrow;
                 if (bn != null)
                 {
                     //совпадает конец  начало lif_time удаляемого рект со хранимой в стрелке
                     if (count_Lif_begin_FC == bn.begin_el_n_FC && count_Lif_end_FC == bn.end_el_n_FC)
                     {
                         if (bn.begin_el_n_TC > n_des_B && bn.end_ei_n_TC > n_des_E)
                         {
                             bn.begin_el_n_TC--;
                             bn.end_ei_n_TC--;
                         }

                     }
                     else {
                         //совпадает начало удаляемой lif_time и начало хранимое в стрелке
                         if (count_Lif_begin_FC == bn.begin_el_n_FC )
                         {
                             if (bn.begin_el_n_TC > n_des_B)
                             {
                                 bn.begin_el_n_TC--;
                             }
                         }
                         //совпадает конец удаляемой lif_time и начало хранимое в стрелке
                         if (count_Lif_end_FC == bn.begin_el_n_FC)
                         {
                             if (bn.begin_el_n_TC > n_des_E)
                             {
                                 bn.begin_el_n_TC--;
                             }

                         }
                         //совпадает конец удаляемой lif_time и конец хранимое в стрелке
                         if (count_Lif_end_FC == bn.end_el_n_FC)
                         {
                             if (bn.end_ei_n_TC > n_des_E)
                             {
                                 bn.end_ei_n_TC--;
                             }

                         }
                         //совпадает начало удаляемой lif_time и конец хранимое в стрелке
                         if (count_Lif_begin_FC == bn.end_el_n_FC)
                         {
                             if (bn.end_ei_n_TC > n_des_B)
                             {
                                 bn.end_ei_n_TC--;
                             }
                         }
                     }

                     ////индекс линии жизни должен совпадать 
                     ////или с  началом стрелки
                     //if (count_Lif == bn.begin_el_n_FC)
                     //{
                     //    //проверяем индекс рект он должен быть больше удаленного рект
                     //    if (bn.begin_el_n_TC > n_des_B)
                     //            //уменьшаем индекс положения рект
                     //            bn.begin_el_n_TC -= 1;
                     //        if (bn.end_ei_n_TC > n_des_E)
                     //            bn.end_ei_n_TC -= 1;
                     
                     //}
                     ////c концом стрелки
                     // if (count_Lif == bn.end_el_n_FC)
                     //{
                     //    //проверяем индекс рект он должен быть больше удаленного рект
                     //    if (bn.begin_el_n_TC > n_des_B)
                     //            //уменьшаем индекс положения рект
                     //            bn.begin_el_n_TC -= 1;
                     //        if (bn.end_ei_n_TC > n_des_E)
                     //            bn.end_ei_n_TC -= 1;
                     
                     //}
  
                 }
                 //стрелка с возвратом
                 SelfArrow str_vozvrat = fd.Children[j] as SelfArrow;
                 if (str_vozvrat != null)
                 {
                     //совпалают линния хизни
                     if (count_Lif_end_FC == str_vozvrat.el_n_FC)
                     {
                         // индекс удаляемой срелки с возвратом меньше чем найденной
                         if (str_vozvrat.el_n_TC > n_des_E)
                         {
                             str_vozvrat.el_n_TC--;
                         }
                     }
                     //совпалают линния хизни
                     if (count_Lif_begin_FC == str_vozvrat.el_n_FC)
                     {
                         // индекс удаляемой срелки с возвратом меньше чем найденной
                         if (str_vozvrat.el_n_TC > n_des_B)
                         {
                             str_vozvrat.el_n_TC--;
                         }
                     }

                 }

            }
        }
        
        
        private void mouseButtonDown(object sender, MouseButtonEventArgs e)
        {
            MainWindow.shared().objectCaptured(this, e.GetPosition(MainWindow.shared().mainCanvas));
        }

        private void lineClicked(object sender, MouseButtonEventArgs e)
        {
            MainWindow.shared().lineClicked(this, e.GetPosition(MainWindow.shared().mainCanvas));
        }

        public void rmObject()
        {
            int f = 0;
            int Casd = MainWindow.shared().mainCanvas.Children.Count;
            //перебираем все стрелки
            for (int j = Casd - 1; j > 0; j--)
            {
                Arrow bn = MainWindow.shared().mainCanvas.Children[j] as Arrow;
                if (bn != null)
                {

                    LifeLine rect_B = MainWindow.shared().mainCanvas.Children[bn.begin_el_n_FC] as LifeLine;
                    LifeLine rect_E = MainWindow.shared().mainCanvas.Children[bn.end_el_n_FC] as LifeLine;

                    //совпадает начало удаляемой lif_time и начало хранимое в стрелке
                    if (this.id == bn.begin_el_n_FC || this.id == bn.end_el_n_FC)
                    {
                        removeArrow(MainWindow.shared().mainCanvas, bn.begin_el_n_TC, bn.end_ei_n_TC, bn.begin_el_n_FC, bn.end_el_n_FC);

                        //удаление линии
                        MainWindow.shared().mainCanvas.Children.RemoveAt(j);
                        //удаление наконечника
                        MainWindow.shared().mainCanvas.Children.RemoveAt(j);
                        //удалени обьекта стрелка
                        MainWindow.shared().mainCanvas.Children.RemoveAt(j);

                        MainWindow.shared().mainCanvas.Children.RemoveAt(j);
                        //  Casd -= 4;

                        //удаление начального рект
                        rect_B.localCanvas.Children.RemoveAt(bn.begin_el_n_TC);
                        //удаление конечного рект
                        rect_E.localCanvas.Children.RemoveAt(bn.end_ei_n_TC);

                        j--;
                    }
                }
                //получаем стрелку 
                //если s линия тоs-1 должен быть обьект стрелка c стрелка с возвратом
                SelfArrow del_v_str = MainWindow.shared().mainCanvas.Children[j] as SelfArrow;
                if (del_v_str != null)
                {
                    if (del_v_str.el_n_FC < (MainWindow.shared().mainCanvas.Children.Count))
                    {
                        LifeLine rect = MainWindow.shared().mainCanvas.Children[del_v_str.el_n_FC] as LifeLine;
                        if (this.id == del_v_str.el_n_FC)
                        {
                            delte_strlka_n_return(MainWindow.shared().mainCanvas, del_v_str.el_n_TC, del_v_str.el_n_FC);

                            MainWindow.shared().mainCanvas.Children.RemoveAt(j);
                            MainWindow.shared().mainCanvas.Children.RemoveAt(j);

                            // Casd -= 2;
                            //((Canvas)sender).Children.RemoveAt(s );
                            rect.localCanvas.Children.RemoveAt(del_v_str.el_n_TC);
                        }
                    }
                }
            }
            dec_life_time(this.id);

            MainWindow.shared().lifeLinesList.Remove(this);
            MainWindow.shared().mainCanvas.Children.Remove(this);
        }
    }
}
